package com.icinfo.cloud.provider.punish.common.datareport.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.enums.YesOrNoEnum;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.common.utils.BaseUtil;
import com.icinfo.cloud.provider.common.utils.SpringContextUtil;
import com.icinfo.cloud.provider.punish.common.datareport.dto.CaseDataReportRecordQueryDto;
import com.icinfo.cloud.provider.punish.common.datareport.dto.CaseDataReportRequestCommonDto;
import com.icinfo.cloud.provider.punish.common.datareport.enums.CaseDataReportOptTypeEnum;
import com.icinfo.cloud.provider.punish.common.datareport.enums.ReportDataTypeEnum;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataReportRecordService;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataReportService;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataReportStageInfoService;
import com.icinfo.cloud.provider.punish.common.datareport.vo.CaseDataReportRecordVo;
import com.icinfo.cloud.provider.punish.config.model.ConfigDictionaryInfo;
import com.icinfo.cloud.provider.punish.config.service.IConfigDictionaryInfoService;
import com.icinfo.cloud.provider.punish.csource.manage.mapper.CaseSourceRegisterMainInfoMapper;
import com.icinfo.cloud.provider.punish.csource.manage.model.CaseSourceRegisterMainInfo;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CasePartiesRecordQueryDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.CaseTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.HandleTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.PartiesReasonTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.mapper.CasePartiesRecordMapper;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseMainDetailInfo;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseMainDetailSimpleInfo;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CasePartiesLegalInfo;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseMainInfoVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CasePartiesInfoVo;
import com.icinfo.framework.common.web.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述：案件数据上报接口实现类-结案信息
 *
 * @author xiangyuyu
 * @date 2022/6/13 20:04
 */
@Slf4j
@Service
public class CaseDataReportCloseServiceImpl implements ICaseDataReportService {

    private static final String TERRITORY_CODE_PREFIX = "001";
    /**
     * 行政处罚结案推送接口
     */
    private static final String CASE_CLOSED_HTTP = "U0odx61fHvb6Jc1f.htm";
    @Resource
    private ICaseMainDetailInfoService caseMainDetailInfoService;
    @Resource
    private ICaseMainInfoService caseMainInfoService;
    @Resource
    private ICaseDataReportStageInfoService caseDataReportStageInfoService;
    @Resource
    private ICaseDataReportRecordService caseDataReportRecordService;
    @Resource
    private CaseDataReportBasicServiceImpl basicService;
    @Resource
    private ICasePartiesRecordService casePartiesRecordService;
    @Resource
    private CasePartiesRecordMapper casePartiesRecordMapper;
    @Resource
    private ICaseMainDetailSimpleInfoService caseMainDetailSimpleInfoService ;
    @Resource
    private CaseSourceRegisterMainInfoMapper caseSourceRegisterMainInfoMapper;
    @Resource
    private IConfigDictionaryInfoService configDictionaryInfoService;
    @Resource
    private ICasePartiesLegalInfoService casePartiesLegalInfoService;
    /**
     * 描述：收集数据上报-结案信息
     *
     * @param caseMainInfoVo {@link CaseMainInfoVo}
     * @param reportDataType 上报数据类型
     * @param isUpdateReReport 是否更新补推
     * @param partyInfo {@link CasePartiesInfoVo} 当事人信息
     * @param optType          更新类型
     * @return {@link JSONObject} 上报数据内容
     * @author xiangyuyu
     * @date 2022-03-31 23:18
     */
    @Override
    public JSONObject reportDataCollect(CaseMainInfoVo caseMainInfoVo, String reportDataType,boolean isUpdateReReport,CasePartiesInfoVo partyInfo,String optType) {
        JSONObject returnInfo = new JSONObject();
        log.info("collectReportCaseClosedInfo start...param-caseMainInfo:{},reportDataType:{}", caseMainInfoVo, reportDataType);
        JSONObject caseClosedInfo = new JSONObject();
        String caseId = caseMainInfoVo.getId();
        String caseTerritoryCode = caseMainInfoVo.getCaseTerritoryCode();
        String sourceDeptCode = TERRITORY_CODE_PREFIX + caseTerritoryCode;
        String partyId = partyInfo.getPartyId();
        CaseDataReportRecordQueryDto queryDto = new CaseDataReportRecordQueryDto();
        queryDto.setCaseId(caseId);
        queryDto.setReportDataType(reportDataType);
        queryDto.setIsTestData(YesOrNoEnum.YES.getCode());
        queryDto.setPartyId(partyId);
        //默认测试数据1
        String envFlag = Constant.STRING_1;
        if (SpringContextUtil.checkIsPrdProfile()) {
            queryDto.setIsTestData(YesOrNoEnum.NO.getCode());
            envFlag = Constant.STRING_0;
        }

        List<CaseDataReportRecordVo> list = caseDataReportRecordService.getCaseDataReportRecord(queryDto);
        String reportActionType = "I";
        if (!ObjectUtils.isEmpty(list) && list.size() > 0) {
            CaseDataReportRecordVo latestRecord = list.get(Constant.INTEGER_0);
            String latestReportResult = latestRecord.getReportResult();
            if (!Constant.STRING_0.equals(latestReportResult)) {
                String oriActionType = latestRecord.getReportActionType();
                reportActionType = "U".equals(oriActionType) ? oriActionType : "I";
            } else {
                reportActionType = "U";
            }
        }
        String caseType = caseMainInfoVo.getCaseType();
        //获取案件详细信息
        CaseMainDetailInfo caseMainDetailInfo;
        if(CaseTypeEnum.SIMPLE_PROCEDURE.getCode().equals(caseType)){
            //简易处罚
            caseMainDetailInfo = new CaseMainDetailInfo();
            CaseMainDetailSimpleInfo caseMainDetailSimpleInfo = caseMainDetailSimpleInfoService.getCaseMainDetailSimpleInfo(caseId);
            if(ObjectUtils.isEmpty(caseMainDetailSimpleInfo)){
                throw new BusinessException("未匹配到简易处罚的案件详情信息-caseId:"+caseId);
            }
            LocalDate caseEndDate = caseMainInfoVo.getCaseEndTime().toLocalDate();
            caseMainDetailInfo.setExecuteFinishDate(caseEndDate);
            caseMainDetailInfo.setCaseFinishDate(caseEndDate);
            caseMainDetailInfo.setExecuteWay("自觉履行");
        } else {
            //TODO：目前暂时将简易处罚之外的案件的宽表数据认为存储在case_main_detail_info,后期如果有新增宽表，得特殊处理
            caseMainDetailInfo = caseMainDetailInfoService.getCaseMainDetailByCaseId(caseId);
        }

        caseClosedInfo.put("recordUniqueIdentity", BaseUtil.createUid());

        /*
            如果当事人id为空，则说明是单当事人/多当事人合并处罚，
            则caseId作为 punishBaseInfoCode，
            否则取当事人id作为 punishBaseInfoCode
         */
        String uid = partyId;
        //是否是多当事人分别处罚
        boolean isMultiplePartiesAndPartPunish = !ObjectUtils.isEmpty(partyId)?true:false;
        if(!isMultiplePartiesAndPartPunish){
            uid = caseId;
        }
        caseClosedInfo.put("punishBaseInfoCode", uid);
        //结案情况-执行结果[非必填]
        //caseClosedInfo.put("casesClosedExecutionResult",  "");
        //结案实缴罚款金额[非必填]
        //caseClosedInfo.put("casesClosedFine","");
        // FIXME: 2022/4/2 是否涉刑职权案件[当前版本默认否]
        caseClosedInfo.put("isAuthorityCase", Constant.STRING_0);
        //结案情况-不予行政处罚（数据上报规则：0-否/1-是）
        String executeWay = caseMainDetailInfo.getExecuteWay();
        if (!ObjectUtils.isEmpty(executeWay)) {
            caseClosedInfo.put("casesClosedExecution", Constant.STRING_0);
        } else {
            caseClosedInfo.put("casesClosedExecution", Constant.STRING_1);
        }
        //其他处理情况[非必填]
        //caseClosedInfo.put("otherDisposals", "");
        //结案日期
        log.info("caseCloseDate:{}",caseMainDetailInfo.getCaseFinishDate());
        caseClosedInfo.put("caseCloseDate", caseMainDetailInfo.getCaseFinishDate());
        //非正常结案原因 之前省处罚没有涉及：unsusalCloseReason
        //接收部门[非必填]
        //caseClosedInfo.put("receiveDept", "");
        // FIXME: 2022/4/2 移送日期[非必填] 目前无移送日期
        //caseClosedInfo.put("deportationDate", );
        caseClosedInfo.put("optType", !ObjectUtils.isEmpty(optType) ? optType :reportActionType);
        caseClosedInfo.put("envFlag", envFlag);
        caseClosedInfo.put("sourceDeptCode", sourceDeptCode);

        //上报人社数据
        if(CaseTypeEnum.NORMAL_PROCEDURE.getCode().equals(caseType)){
            JSONObject rsJSON = new JSONObject();
            CaseSourceRegisterMainInfo caseSourceRegisterMainInfo = caseSourceRegisterMainInfoMapper.selectByPrimaryKey(caseId);
            if(caseSourceRegisterMainInfo != null && StrUtil.isNotEmpty(caseSourceRegisterMainInfo.getProjectType())){
                rsJSON.put("isRelateFarmer", caseSourceRegisterMainInfo.getIsRelateFarmer());
                //获取对应的project_type
                ConfigDictionaryInfo configDictionaryInfo = configDictionaryInfoService.getConfigDictionaryByFieldCodeAndDicCode("RS_PROJECT_TYPE", caseSourceRegisterMainInfo.getProjectType());
                if(configDictionaryInfo != null){
                    rsJSON.put("projectType", configDictionaryInfo.getDicName());
                }
            }
            //获取单位类型
            CasePartiesLegalInfo casePartiesLegalInfo = casePartiesLegalInfoService.getInfoByCaseId(caseId);
            if(casePartiesLegalInfo != null && StrUtil.isNotEmpty(casePartiesLegalInfo.getLegalIndustryType())){
                //获取对应的RS_INDUSTRY_TYPE
                ConfigDictionaryInfo industryInfo = configDictionaryInfoService.getConfigDictionaryByFieldCodeAndDicCode("RS_INDUSTRY_TYPE", casePartiesLegalInfo.getLegalIndustryType());
                if(industryInfo != null){
                    rsJSON.put("legalIndustryType", industryInfo.getDicName());
                }
            }
            if(StrUtil.isNotEmpty(caseMainDetailInfo.getPersonReasonDetail())){
                //人社结案时信息
                rsJSON.put("personReasonDetail", caseMainDetailInfo.getPersonReasonDetail());
            }
            caseClosedInfo.put("prepareJsonFields", rsJSON.toJSONString());
        }
        returnInfo.put("caseClosedInfo", caseClosedInfo);
        //到dataReport时清空该键值
        returnInfo.put("reportActionType", !ObjectUtils.isEmpty(optType)?optType:reportActionType);
        returnInfo.put("envFlag", envFlag);
        log.info("collectReportCaseClosedInfo end...result-returnInfo", returnInfo);
        return returnInfo;
    }

    /**
     * 描述：数据上报-close
     *
     * @param dto          {@link CaseDataReportRequestCommonDto}
     * @param partyInfo    {@link CasePartiesInfoVo} 当事人信息
     * @param caseMainInfo {@link CaseMainInfoVo} 案件主体信息
     * @return {@link Result<String>} 上报结果
     * @author xiangyuyu
     * @date 2022-03-30 21:23
     */
    @Override
    public Result<String> singleCaseReport(CaseDataReportRequestCommonDto dto, CasePartiesInfoVo partyInfo, CaseMainInfoVo caseMainInfo) {
        log.info("dataReportClose start... dto:{}", dto);
        String caseId = dto.getCaseId();
        String optType = dto.getOptType();
        if(!ObjectUtils.isEmpty(optType)){
            if(!CaseDataReportOptTypeEnum.isLegalEnumCode(optType)){
                throw new BusinessException("请指定有效的数据上报更新类型枚举(I：新增， U：修改； D：删除)");
            }
        }
        if (!caseDataReportRecordService.personalCheckIsAllowDataReport(caseId, null)) {
            log.info("该案件暂不开启数据上报-caseId:{}", caseId);
            return Result.error("该案件暂不开启数据上报-caseId:" + caseId);
        }
        List<CasePartiesInfoVo> partiesInfo = new ArrayList<>();
        if (ObjectUtils.isEmpty(partyInfo)) {
            //获取当事人信息
            if (ObjectUtils.isEmpty(caseMainInfo)) {
                caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
            }
            String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
            String handleType = caseMainInfo.getHandleType();
            CasePartiesRecordQueryDto queryDto = new CasePartiesRecordQueryDto(caseId, null, YesOrNoEnum.NO.getCode());
            partiesInfo = casePartiesRecordService.getCasePartiesInfoList(queryDto);
            if (!(PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)
                    && HandleTypeEnum.PART_PUNISH.getCode().equals(handleType))
            ) {
                //只取第一个当事人信息
                List<CasePartiesInfoVo> tmp = new ArrayList<>();
                tmp.add(partiesInfo.get(Constant.INTEGER_0));
                partiesInfo = tmp;
                partiesInfo.forEach(p -> p.setPartyId(null));
            }
        } else {
            partiesInfo.add(partyInfo);
        }
        for (CasePartiesInfoVo p : partiesInfo) {
            String partyId = p.getPartyId();
            try {
                if (caseDataReportRecordService.getIsAllowDataReport(caseId)) {
                    String errorMsg;
                    if(ObjectUtils.isEmpty(caseMainInfo)){
                        //根据案件id查询案件信息
                        caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
                    }
                    String uri = CASE_CLOSED_HTTP;
                    String reportDataType = ReportDataTypeEnum.CASE_CLOSED.getCode();
                    JSONObject tmpData = reportDataCollect(caseMainInfo, reportDataType,false,p, optType);
                    JSONObject reportData = new JSONObject(8);
                    reportData.put("reportActionType", !ObjectUtils.isEmpty(optType)?optType:tmpData.get("reportActionType"));
                    reportData.put("envFlag", tmpData.get("envFlag"));
                    tmpData.remove("envFlag");
                    tmpData.remove("reportActionType");
                    reportData.put("caseClosedInfo", tmpData);
                    Map<String, String> params = new HashMap<>(20);
                    for (Map.Entry<String, Object> e : reportData.entrySet()) {
                        params.put(e.getKey(), (ObjectUtils.isEmpty(e.getValue()) ? "" : e.getValue().toString()));
                    }
                    errorMsg = caseDataReportRecordService.dataReport(uri, reportDataType, params, caseMainInfo);
                    log.info("dataReportClose end");
                    if (ObjectUtils.isEmpty(errorMsg)) {
                        caseDataReportStageInfoService.dealAfterReport(caseId, true, ReportDataTypeEnum.CASE_CLOSED.getCode(), null,partyId);
                    } else {
                        if(errorMsg.contains(Constant.STRING_RECORD_EXISTS)){
                            caseDataReportStageInfoService.dealAfterReport(caseId, true, ReportDataTypeEnum.CASE_CLOSED.getCode(), errorMsg,partyId);
                        } else if(errorMsg.contains(Constant.STRING_ERROR_SIGN)) {
                            caseDataReportRecordService.reportAgain(dto, partyInfo, caseMainInfo, this, reportDataType);
                        } else {
                            caseDataReportStageInfoService.dealAfterReport(caseId, false, ReportDataTypeEnum.CASE_CLOSED.getCode(), errorMsg,partyId);
                        }
                        return Result.error(errorMsg);
                    }
                } else {
                    String tmpMsg = "该部门是否允许上报数据按钮处于关闭状态,caseId:" + caseId;
                    throw new BusinessException(tmpMsg);
                }

            } catch (Exception e) {
                e.printStackTrace();
                caseDataReportStageInfoService.dealAfterReport(caseId, false, ReportDataTypeEnum.CASE_CLOSED.getCode(), e.getMessage(),partyId);
                return Result.error("dataReportClose catch exception：" + e.getMessage());
            }
        }
        return Result.success("上报成功");
    }




    /**
     * 【V2.0.0】描述：结案信息-数据批量上报
     * @param baseInfoReportFailCaseIdList 上报失败的案件id列表
     * @return 上报失败案件id列表
     * @author xiangyuyu
     * @date 2022-06-13 16:02
     */
    @Override
    public List<String> batchCaseReport(List<String> baseInfoReportFailCaseIdList) {
        if(ObjectUtils.isEmpty(baseInfoReportFailCaseIdList)){
            baseInfoReportFailCaseIdList = new ArrayList<>();
        }
        LocalDateTime startTime = LocalDateTime.now();
        log.info("closeInfoReportBatch start-startTime:{}", startTime);
        //6、查看2天前是否存在"案件终结报告审批通过"的案件
        List<String> shouldUploadCaseOverReportInfo = caseMainDetailInfoService.getCaseIdListShouldReportCaseOverInfo();
        if (!ObjectUtils.isEmpty(shouldUploadCaseOverReportInfo) && shouldUploadCaseOverReportInfo.size() > 0) {
            log.info("案件终结报告审批通过数量:{}", shouldUploadCaseOverReportInfo.size());
            List<String> finalBaseInfoReportFailCaseIdList = baseInfoReportFailCaseIdList;
            shouldUploadCaseOverReportInfo.forEach(e -> {
                if (!finalBaseInfoReportFailCaseIdList.contains(e)) {
                    CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(e);
                    if (!caseDataReportRecordService.personalCheckIsAllowDataReport(e, caseMainInfo)) {
                        return;
                    }
                    String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
                    String handleType = caseMainInfo.getHandleType();
                    CasePartiesRecordQueryDto queryDto = new CasePartiesRecordQueryDto(e, null,YesOrNoEnum.NO.getCode());
                    List<CasePartiesInfoVo> partiesInfo = casePartiesRecordService.getCasePartiesInfoList(queryDto);
                    if (!(PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)
                            && HandleTypeEnum.PART_PUNISH.getCode().equals(handleType))
                    ) {
                        //只取第一个当事人信息
                        List<CasePartiesInfoVo> tmp = new ArrayList<>();
                        tmp.add(partiesInfo.get(Constant.INTEGER_0));
                        partiesInfo = tmp;
                        partiesInfo.forEach(p -> p.setPartyId(null));
                    }
                    CaseDataReportRequestCommonDto dto = new CaseDataReportRequestCommonDto();
                    dto.setCaseId(e);
                    for (CasePartiesInfoVo partyInfo : partiesInfo) {
                        String partyId = partyInfo.getPartyId();
                        //校验是否需要上报
                        boolean isShouldReport = caseDataReportStageInfoService.checkIsShouldReport(ReportDataTypeEnum.CASE_CLOSED.getCode(), e,partyId);
                        if (isShouldReport) {
                            //查看案件基础信息是否上报
                            if (!caseDataReportStageInfoService.checkStageInfoIsReportSuccess(ReportDataTypeEnum.BASE.getCode(), e,partyId)) {
                                Result<String> result = basicService.singleCaseReport(dto,null,caseMainInfo);
                                if (!caseDataReportRecordService.analyseResultToJudgeIsReportSuccess(result)) {
                                    finalBaseInfoReportFailCaseIdList.add(e);
                                } else {
                                    singleCaseReport(dto,partyInfo,caseMainInfo);
                                }
                            } else {
                                singleCaseReport(dto,partyInfo,caseMainInfo);
                            }
                        }
                    }
                }
            });
        } else {
            log.info("date:{},无案件终结报告审批通过",startTime);
        }

        LocalDateTime endTime = LocalDateTime.now();
        Duration duration = Duration.between(startTime, endTime);
        long seconds = duration.getSeconds();
        log.info("closeInfoReportBatch end-endTime:{},consume:{} s", endTime, seconds);
        return baseInfoReportFailCaseIdList;
    }

    /**
     * 描述：单个案件重新数据上报（U）
     *
     * @param caseId 案件id
     * @param partyInfo    {@link CasePartiesInfoVo} 当事人信息
     * @param caseMainInfo {@link CaseMainInfoVo} 案件主体信息
     * @return {@link Result <String>} 上报结果
     * @author xiangyuyu
     * @date 2022-06-13 18:52
     */
    @Override
    public Result<String> singleCaseReportAgain(String caseId, CasePartiesInfoVo partyInfo, CaseMainInfoVo caseMainInfo) {
        return null;
    }

    /**
     * 描述：批量案件重新数据上报（U）
     *
     * @return {@link Result <String>} 上报失败案件id列表
     * @author xiangyuyu
     * @date 2022-06-13 18:52
     */
    @Override
    public List<String> batchCaseReportAgain() {
        return null;
    }
}
